import path from 'path';
import fs from 'fs';
import { Md5 } from 'ts-md5';
import MLog from '../util/Log/index';

const TAG = 'CommonUtil';

class CommonUtil {
  private static instance: CommonUtil;

  public static getInstance() {
    if (!this.instance) {
      this.instance = new CommonUtil();
    }
    return this.instance;
  }

  public resolveHtmlPath(htmlFileName: string) {
    if (process.env.NODE_ENV === 'development') {
      const port = process.env.PORT || 1212;
      const url = new URL(`http://localhost:${port}`);
      url.pathname = htmlFileName;
      return url.href;
    }
    return `file://${path.resolve(__dirname, '../renderer/', htmlFileName)}`;
  }

  public sleep(ms: number) {
    return new Promise((resolve) =>
      setTimeout(() => {
        resolve('');
      }, ms)
    );
  }

  public getArrMd5(arr: string[]) {
    let res = '';
    arr.forEach((value) => {
      res += value;
    });
    return Md5.hashStr(res);
  }

  public getAllFiles(dir: string, suffix: string) {
    const fileList: string[] = [];
    this.dfsGetFile(dir, fileList, suffix);
    return fileList;
  }

  public dfsGetFile(dir: string, filesList: Array<string>, suffix: string) {
    const files = fs.readdirSync(dir);
    files.forEach((file) => {
      const filePath = `${dir}/${file}`;
      const states = fs.statSync(filePath);
      if (states.isDirectory()) {
        this.dfsGetFile(filePath, filesList, suffix);
      } else {
        if (file.endsWith(suffix)) {
          filesList.push(filePath);
        }
      }
    });
  }
  public getAllFilesExclude(dir: string, suffix: string) {
    const fileList: string[] = [];
    this.dfsGetFileExclude(dir, fileList, suffix);
    return fileList;
  }

  public dfsGetFileExclude(
    dir: string,
    fileList: Array<string>,
    suffix: string
  ) {
    const files = fs.readdirSync(dir);
    files.forEach((file) => {
      const filePath = `${dir}/${file}`;
      const states = fs.statSync(filePath);
      if (states.isDirectory()) {
        this.dfsGetFileExclude(filePath, fileList, suffix);
      } else {
        if (!file.endsWith(suffix)) {
          fileList.push(filePath);
        }
      }
    });
  }

  public rmDir(dir: string) {
    if (fs.existsSync(dir)) {
      const dirs: string[] = [];
      const files = fs.readdirSync(dir);
      files.forEach((file) => {
        const childPath = path.join(dir, file);
        if (fs.statSync(childPath).isDirectory()) {
          this.rmDir(childPath);
          dirs.push(childPath);
        } else {
          fs.unlinkSync(childPath);
        }
      });
      dirs.forEach((fir) => fs.rmdirSync(fir));
    }
  }

  public mkdir(dirname: string, callback: () => void) {
    const self = this;
    fs.exists(dirname, (exists) => {
      if (exists) {
        callback();
      } else {
        self.mkdir(path.dirname(dirname), () => {
          fs.mkdir(dirname, callback);
        });
      }
    });
  }
}
export default CommonUtil;
